#include "vg/text.h"
#include "draw.h"

using namespace anip;

class vg::Text::Renderer : public GraphicsRenderer
{
private:
	Text& _t;

public:
	Renderer(Text& s) : _t(s) { _version = s.version(); }

	GraphicObject& graphicObject() const override { return _t; }
	void render(GraphicsRenderContext& cxt) override;
};

vg::Text::Text(const Font& f, const wstring& text, invec2 pos):
	font(f), text(text), position(pos)
{}

vec2 vg::Text::estimateSize(float time)
{
	const int testSize = 50;

	TextRenderer::Options opt;// = options;
	opt.lineSpacing = (int)lineSpacing[time];
	opt.maxWidth = (int)maxWidth[time];

	font.size = testSize;
	auto layout = TextRenderer::layoutString(text[time], font, opt);
	vec2 size = TextRenderer::measureString(*layout);
	delete layout;

	return size / (float)testSize * lineSize[time];
}

void vg::Text::Renderer::render(GraphicsRenderContext& cxt)
{
	// ANIP_UNDONE: text should render according to its physical size!

	vec2 pos = _t.position[_currentFrame];
	float fsize = _t.lineSize[_currentFrame];
	if (fsize < 1) return;
	_t.font.size = (int)round(fsize);

	TextRenderer::Options opt;// = _t.options;
	opt.lineSpacing = (int)_t.lineSpacing[_currentFrame];
	opt.maxWidth = (int)_t.maxWidth[_currentFrame];

	Draw::text(pos, _t.text[_currentFrame], 
		_t.color[_currentFrame], _t.font, { 0, 0 }, opt);
}

GraphicsRenderer* anip::vg::Text::createRenderer()
{
	return new Renderer(*this);
}

serializer_implementation(vg::Text)(Primitive& obj, std::ostream& out)
{
	auto& s = (Text&)obj;
	binaryWrite(s.position, out);
	binaryWrite(s.text, out);
	binaryWrite(s.color, out);
	binaryWrite(s.lineSize, out);
	binaryWrite(s.maxWidth, out);
	binaryWrite(s.lineSpacing, out);
	// ANIP_TODO: serialize font from the GlobalStore
}

deserializer_implementation(vg::Text)(std::istream& in)
{
	auto s = new Text();
	binaryRead(s->position, in);
	binaryRead(s->text, in);
	binaryRead(s->color, in);
	binaryRead(s->lineSize, in);
	binaryRead(s->maxWidth, in);
	binaryRead(s->lineSpacing, in);
	return s;
}